//ThinkTemplate 用js实现了ThinkPHP的模板引擎。
//用户可以在手机客户端中用ThinkPHP的模板引擎。
//@author luofei614<http://weibo.com/luofei614>
//
var ThinkTemplate = {
    tags: ['Include', 'Volist', 'Foreach', 'For', 'Empty', 'Notempty', 'Present', 'Notpresent', 'Compare', 'If', 'Elseif', 'Else', 'Swith', 'Case', 'Default', 'Var', 'Range'],
    parse: function (tplContent, vars) {
        var render = function () {
            tplContent = '<% var key,mod=0;%>' + tplContent;//定义模板中循环需要使用的到变量
            $.each(ThinkTemplate.tags, function (k, v) {
                tplContent = ThinkTemplate['parse' + v](tplContent);
            });
            return ThinkTemplate.template(tplContent, vars);
        };

        return render();
    },
    //解析 <% %> 标签
    template: function (text, vars) {
        var source = "";
        var index = 0;
        var escapes = {
            "'": "'",
            '\\': '\\',
            '\r': 'r',
            '\n': 'n',
            '\t': 't',
            '\u2028': 'u2028',
            '\u2029': 'u2029'
        };
        var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
        text.replace(/<%=([\s\S]+?)%>|<%([\s\S]+?)%>/g, function (match, interpolate, evaluate, offset) {
            var p = text.slice(index, offset).replace(escaper, function (match) {
                return '\\' + escapes[match];
            });
            if ('' != $.trim(p)) {
                source += "__p+='" + p + "';\n";
            }

            if (evaluate) {
                source += evaluate + "\n";
            }
            if (interpolate) {
                source += "if( 'undefined'!=typeof(" + interpolate + ") && (__t=(" + interpolate + "))!=null) __p+=__t;\n";
            }
            index = offset + match.length;
            return match;
        });
        source += "__p+='" + text.slice(index).replace(escaper, function (match) {
            return '\\' + escapes[match];
        }) + "';\n";//拼接剩余的字符串

        source = "var __t,__p='',__j=Array.prototype.join," +
        "print=function(){__p+=__j.call(arguments,'');};\n" +
        "with(obj){\n" +
        source +
        "}\n" +
        "return __p;\n";
        try {
            render = new Function('obj', source);

        } catch (e) {
            e.source = source;
            throw e;
        }
        return render(vars);
    },
    parseVar: function (tplContent) {
        var matcher = /\{\$(.*?)\}/g
        return tplContent.replace(matcher, function (match, varname, offset) {
            //支持定义默认值
            if (varname.indexOf('|') != -1) {
                var arr = varname.split('|');
                var name = arr[0];
                var defaultvalue = '""';
                arr[1].replace(/default=(.*?)$/ig, function (m, v, o) {
                    defaultvalue = v;
                });
                return '<% ' + name + '?print(' + name + '):print(' + defaultvalue + ');  %>';
            }
            return '<%=' + varname + '%>';
        });
    },
    //include标签解析 路径需要写全，写为 Action:method, 暂不支持变量。 
    parseInclude: function (tplContent) {
        var include = /<include (.*?)\/?>/ig;
        tplContent = tplContent.replace(include, function (m, v, o) {
            var $think = $('<think ' + v + ' />');
            var file = $think.attr('file').replace(':', '/') + '.html';
            var content = '';
            //加载模板
            $.ajax({
                dataType: 'text',
                url: file,
                cache: false,
                async: false,//同步请求
                success: function (d, s, x) {
                    content = d;
                },
                error: function () {
                    //pass
                }
            });
            return content;
        });
        tplContent = tplContent.replace('</include>', '');//兼容浏览器中元素自动闭合的情况
        return tplContent;
    },
    //volist标签解析
    parseVolist: function (tplContent) {
        var voliststart = /<volist (.*?)>/ig;
        var volistend = /<\/volist>/ig;
        //解析volist开始标签
        tplContent = tplContent.replace(voliststart, function (m, v, o) {
            //属性分析
            var $think = $('<think ' + v + ' />');
            var name = $think.attr('name');
            var id = $think.attr('id');
            var empty = $think.attr('empty') || '';
            var key = $think.attr('key') || 'i';
            var mod = $think.attr('mod') || '2';
            //替换为代码
            return '<% if("undefined"==typeof(' + name + ') || ThinkTemplate.empty(' + name + ')){' +
            ' print(\'' + empty + '\');' +
            ' }else{ ' +
            key + '=0;' +
            ' $.each(' + name + ',function(key,' + id + '){' +
            ' mod=' + key + '%' + mod + ';' +
            ' ++' + key + ';' +
            ' %>';
        });
        //解析volist结束标签
        tplContent = tplContent.replace(volistend, '<% }); } %>');
        return tplContent;
    },
    //解析foreach标签
    parseForeach: function (tplContent) {
        var foreachstart = /<foreach (.*?)>/ig;
        var foreachend = /<\/foreach>/i;
        tplContent = tplContent.replace(foreachstart, function (m, v, o) {
            var $think = $('<think ' + v + ' />');
            var name = $think.attr('name');
            var item = $think.attr('item');
            var key = $think.attr('key') || 'key';
            return '<% $.each(' + name + ',function(' + key + ',' + item + '){  %>'
        });
        tplContent = tplContent.replace(foreachend, '<% }); %>');
        return tplContent;
    },
    parseFor: function (tplContent) {
        var forstart = /<for (.*?)>/ig;
        var forend = /<\/for>/ig;
        tplContent = tplContent.replace(forstart, function (m, v, o) {
            var $think = $('<think ' + v + ' />');
            var name = $think.attr('name') || 'i';
            var comparison = $think.attr('comparison') || 'lt';
            var start = $think.attr('start') || '0';
            if ('$' == start.substr(0, 1)) {
                start = start.substr(1);
            }
            var end = $think.attr('end') || '0';
            if ('$' == end.substr(0, 1)) {
                end = end.substr(1);
            }
            var step = $think.attr('step') || '1';
            if ('$' == step.substr(0, 1)) {
                step = step.substr(1);
            }
            return '<% for(var ' + name + '=' + start + ';' + ThinkTemplate.parseCondition(name + comparison + end) + ';i=i+' + step + '){  %>'
        });
        tplContent = tplContent.replace(forend, '<% } %>');
        return tplContent;
    },
    //empty标签
    parseEmpty: function (tplContent) {
        var emptystart = /<empty (.*?)>/ig;
        var emptyend = /<\/empty>/ig;
        tplContent = tplContent.replace(emptystart, function (m, v, o) {
            var name = $('<think ' + v + ' />').attr('name');
            return '<% if("undefined"==typeof(' + name + ') || ThinkTemplate.empty(' + name + ')){ %>';
        });
        tplContent = tplContent.replace(emptyend, '<% } %>');
        return tplContent;
    },
    //notempty 标签解析
    parseNotempty: function (tplContent) {
        var notemptystart = /<notempty (.*?)>/ig;
        var notemptyend = /<\/notempty>/ig;
        tplContent = tplContent.replace(notemptystart, function (m, v, o) {
            var name = $('<think ' + v + ' />').attr('name');
            return '<% if("undefined"!=typeof(' + name + ') && !ThinkTemplate.empty(' + name + ')){ %>';
        });
        tplContent = tplContent.replace(notemptyend, '<% } %>');
        return tplContent;
    },
    //present标签解析
    parsePresent: function (tplContent) {
        var presentstart = /<present (.*?)>/ig;
        var presentend = /<\/present>/ig;
        tplContent = tplContent.replace(presentstart, function (m, v, o) {
            var name = $('<think ' + v + ' />').attr('name');
            return '<% if("undefined"!=typeof(' + name + ')){ %>';
        });
        tplContent = tplContent.replace(presentend, '<% } %>');
        return tplContent;
    },
    //notpresent 标签解析
    parseNotpresent: function (tplContent) {
        var notpresentstart = /<notpresent (.*?)>/ig;
        var notpresentend = /<\/notpresent>/ig;
        tplContent = tplContent.replace(notpresentstart, function (m, v, o) {
            var name = $('<think ' + v + ' />').attr('name');
            return '<% if("undefined"==typeof(' + name + ')){ %>';
        });
        tplContent = tplContent.replace(notpresentend, '<% } %>');
        return tplContent;
    },
    parseCompare: function (tplContent) {
        var compares = {
            "compare": "==",
            "eq": "==",
            "neq": "!=",
            "heq": "===",
            "nheq": "!==",
            "egt": ">=",
            "gt": ">",
            "elt": "<=",
            "lt": "<"
        };
        $.each(compares, function (type, sign) {
            var start = new RegExp('<' + type + ' (.*?)>', 'ig');
            var end = new RegExp('</' + type + '>', 'ig');
            tplContent = tplContent.replace(start, function (m, v, o) {
                var $think = $('<think ' + v + ' />');
                var name = $think.attr('name');
                var value = $think.attr('value');
                if ("compare" == type && $think.attr('type')) {
                    sign = compares[$think.attr('type')];
                }
                if ('$' == value.substr(0, 1)) {
                    //value支持变量
                    value = value.substr(1);
                } else {
                    value = '"' + value + '"';
                }
                return '<% if(' + name + sign + value + '){  %>';
            });
            tplContent = tplContent.replace(end, '<% } %>');

        });
        return tplContent;
    },
    //解析if标签
    parseIf: function (tplContent) {
        var ifstart = /<if (.*?)>/ig;
        var ifend = /<\/if>/ig;
        tplContent = tplContent.replace(ifstart, function (m, v, o) {
            var condition = $('<think ' + v + ' />').attr('condition');
            return '<% if(' + ThinkTemplate.parseCondition(condition) + '){ %>';
        });
        tplContent = tplContent.replace(ifend, '<% } %>');
        return tplContent;
    },
    //解析elseif
    parseElseif: function (tplContent) {
        var elseif = /<elseif (.*?)\/?>/ig;
        tplContent = tplContent.replace(elseif, function (m, v, o) {
            var condition = $('<think ' + v + '  />').attr('condition');
            return '<% }else if(' + ThinkTemplate.parseCondition(condition) + '){ %>';
        });
        tplContent = tplContent.replace('</elseif>', '');
        return tplContent;
    },
    //解析else标签
    parseElse: function (tplContent) {
        var el = /<else\s*\/?>/ig
        tplContent = tplContent.replace(el, '<% }else{ %>');
        tplContent = tplContent.replace('</else>', '');
        return tplContent;
    },
    //解析swith标签
    parseSwith: function (tplContent) {
        var switchstart = /<switch (.*?)>(\s*)/ig;
        var switchend = /<\/switch>/ig;
        tplContent = tplContent.replace(switchstart, function (m, v, s, o) {
            var name = $('<think ' + v + ' >').attr('name');
            return '<% switch(' + name + '){ %>';
        });
        tplContent = tplContent.replace(switchend, '<% } %>');
        return tplContent;
    },
    //解析case标签
    parseCase: function (tplContent) {
        var casestart = /<case (.*?)>/ig;
        var caseend = /<\/case>/ig;
        var breakstr = '';
        tplContent = tplContent.replace(casestart, function (m, v, o) {
            var $think = $('<think ' + v + '  />');
            var value = $think.attr('value');
            if ('$' == value.substr(0, 1)) {
                value = value.substr(1);
            } else {
                value = '"' + value + '"';
            }
            if ('false' != $think.attr('break')) {
                breakstr = '<% break; %> ';
            }
            return '<% case ' + value + ':  %>';
        });
        tplContent = tplContent.replace(caseend, breakstr);
        return tplContent;
    },
    //解析default标签
    parseDefault: function (tplContent) {
        var defaulttag = /<default\s*\/?>/ig;
        tplContent = tplContent.replace(defaulttag, '<% default: %>');
        tplContent = tplContent.replace('</default>', '');
        return tplContent;
    },
    //解析in,notin,between,notbetween 标签
    parseRange: function (tplContent) {
        var ranges = ['in', 'notin', 'between', 'notbetween'];
        $.each(ranges, function (k, tag) {
            var start = new RegExp('<' + tag + ' (.*?)>', 'ig');
            var end = new RegExp('</' + tag + '>', 'ig');
            tplContent = tplContent.replace(start, function (m, v, o) {
                var $think = $('<think ' + v + ' />');
                var name = $think.attr('name');
                var value = $think.attr('value');
                if ('$' == value.substr(0, 1)) {
                    value = value.substr(1);
                } else {
                    value = '"' + value + '"';
                }
                switch (tag) {
                    case "in":
                        var condition = 'ThinkTemplate.inArray(' + name + ',' + value + ')';
                        break;
                    case "notin":
                        var condition = '!ThinkTemplate.inArray(' + name + ',' + value + ')';
                        break;
                    case "between":
                        var condition = name + '>=' + value + '[0] && ' + name + '<=' + value + '[1]';
                        break;
                    case "notbetween":
                        var condition = name + '<' + value + '[0] || ' + name + '>' + value + '[1]';
                        break;
                }
                return '<% if(' + condition + '){ %>'
            });
            tplContent = tplContent.replace(end, '<% } %>')
        });
        return tplContent;
    },
    //扩展
    extend: function (name, cb) {
        name = name.substr(0, 1).toUpperCase() + name.substr(1);
        this.tags.push(name);
        this['parse' + name] = cb;
    },
    //判断是否在数组中，支持判断object类型的数据
    inArray: function (name, value) {
        if ('string' == $.type(value)) {
            value = value.split(',');
        }
        var ret = false;
        $.each(value, function (k, v) {
            if (v == name) {
                ret = true;
                return false;
            }
        });
        return ret;
    },
    empty: function (data) {
        if (!data)
            return true;
        if ('array' == $.type(data) && 0 == data.length)
            return true;
        if ('object' == $.type(data) && 0 == Object.keys(data).length)
            return true;
        return false;
    },
    parseCondition: function (condition) {
        var conditions = {
            "eq": "==",
            "neq": "!=",
            "heq": "===",
            "nheq": "!==",
            "egt": ">=",
            "gt": ">",
            "elt": "<=",
            "lt": "<",
            "or": "||",
            "and": "&&",
            "\\$": ""
        };
        $.each(conditions, function (k, v) {
            var matcher = new RegExp(k, 'ig');
            condition = condition.replace(matcher, v);
        });
        return condition;
    }


};

//TPMobi框架
//实现用ThinkPHP做手机客户端
//@author luofei614<http://weibo.com/luofei614>
var TPM = {
    op: {
        api_base: '',//接口基地址，末尾不带斜杠
        api_index: '/Index/index',//首页请求地址
        main: "main",//主体层的ID
        routes: {}, //路由,支持参数如:id 支持通配符*
        error_handle: false,//错误接管函数
        _before: [],
        _ready: [],//UI回调函数集合
        single: true,//单一入口模式

        ajax_wait: ".ajax_wait",//正在加载层的选择符
        ajax_timeout: 15000,//ajax请求超时时间
        ajax_data_type: '',//请求接口类型 如json，jsonp
        ajax_jsonp_callback: 'callback',//jsonp 传递的回调函数参数名词

        before_request_api: false,//请求接口之前的hook
        //请求接口之后的hook,处理TP的success和error
        after_request_api: function (data, url) {
            if (data.info) {
                TPM.info(data.info, function () {
                    if (data.url) {
                        TPM.http(data.url);
                    } else if (1 == data.status) {
                        //如果success， 刷新数据
                        TPM.reload(TPM.op.main);
                    }
                });
                return false;
            }
        },

        anchor_move_speed: 500, //移动到锚点的速度

        tpl_path_var: '_think_template_path',//接口指定模板

        tpl_parse_string: {
            '../Public': './Public'
        },//模板替换变量

        //指定接口请求的header
        headers: {
            'client': 'PhoneClient',
            //跨域请求时，不会带X-Requested-with 的header，会导致服务认为不是ajax请求，所以这样手动加上这个header 。
            'X-Requested-With': 'XMLHttpRequest'
        },

        tpl: ThinkTemplate.parse//模板引擎

    },
    config: function (options) {
        $.extend(this.op, options);
    },
    ready: function (fun) {
        this.op._ready.push(fun);
    },
    before: function (fun) {
        this.op._before.push(fun);
    },
    //输出错误
    error: function (errno, msg) {
        TPM.alert('错误[' + errno + ']：' + msg);
    },
    info: function (msg, cb) {
        if ('undefined' == typeof(tpm_info)) {
            alert(msg);
            if ($.isFunction(cb)) cb();
        } else {
            tpm_info(msg, cb);
        }
    },
    alert: function (msg, cb, title) {
        if ('undefined' == typeof(tpm_alert)) {
            alert(msg);
            if ($.isFunction(cb)) cb();
        } else {
            tpm_alert(msg, cb, title);
        }
    },
    //初始化运行
    run: function (options, vars) {
        if (!this.defined(window.jQuery) && !this.defined(window.Zepto)) {
            this.error('-1', '请加载jquery或zepto');
            return;
        }
        //如果只设置api_base 可以只传递一个字符串。
        if ('string' == $.type(options)) {
            options = {api_base: options};
        }
        //配置处理
        options = options || {};
        this.config(options);
        $.ajaxSetup({
            error: this.ajaxError,
            timeout: this.op.ajax_timeout || 5000,
            cache: false,
            headers: this.op.headers
        });
        var _self = this;
        //ajax加载状态
        window.TPMshowAjaxWait = true;
        $(document).ajaxStart(function () {
                //在程序中可以设置TPMshowAjaxWait为false,终止显示等待层。
                if (window.TPMshowAjaxWait) $(_self.op.ajax_wait).show();
            }
        ).ajaxStop(function () {
                $(_self.op.ajax_wait).hide();
            });
        $(document).ready(function () {
            //标签解析
            vars = vars || {};
            var render = function (vars) {
                var tplcontent = $('body').html();
                tplcontent = tplcontent.replace(/&lt;%/g, '<%');
                tplcontent = tplcontent.replace(/%&gt;/g, '%>');
                var html = _self.parseTpl(tplcontent, vars);
                $('body').html(html);
                if (!_self.op.single) {

                    $.each(_self.op._ready, function (k, fun) {
                        fun($);
                    });
                }
            }
            if ('string' == $.type(vars)) {
                _self.sendAjax(vars, {}, 'get', function (response) {
                    render(response);
                });
            } else {
                render(vars);
            }


            if (_self.op.single) {
                //单一入口模式
                _self.initUI(document);
                var api_url = '' != location.hash ? location.hash.substr(1) : _self.op.api_index;
                _self.op._old_hash = location.hash;
                _self.http(api_url);
                //监听hash变化
                var listenHashChange = function () {
                    if (location.hash != _self.op._old_hash) {
                        var api_url = '' != location.hash ? location.hash.substr(1) : _self.op.api_index;
                        _self.http(api_url);
                    }
                    setTimeout(listenHashChange, 50);
                }
                listenHashChange();
            }
        });
    },
    //初始化界面
    initUI: function (_box) {
        //调用自定义加载完成后的UI处理函数,自定义事件绑定先于系统绑定，可以控制系统绑定函数的触发。
        var selector = function (obj) {
            var $obj = $(obj, _box)
            return $obj.size() > 0 ? $obj : $(obj);
        };

        $.each(this.op._before, function (k, fun) {
            fun(selector);
        })

        var _self = this;
        //A标签， 以斜杠开始的地址才会监听，不然会直接打开
        $('a[href^="/"],a[href^="./"]', _box).click(function (e) {
            if (false === e.result)  return; //如果自定义事件return false了， 不再指向请求操作
            e.preventDefault();
            //如果有tpl属性，则光请求模板
            var url = $(this).attr('href');
            if (undefined !== $(this).attr('tpl')) {
                url = '.' + url + '.html';
            }
            //绝对地址的链接不过滤
            _self.http(url, $(this).attr('rel'));
        });
        //form标签的处理
        $('form[action^="/"],form[action^="./"]', _box).submit(function (e) {
            if (false === e.result)  return; //如果自定义事件return false了， 不再指向请求操作
            e.preventDefault();
            var url = $(this).attr('action');
            if (undefined !== $(this).attr('tpl')) {
                url = '.' + url + '.html';
            }
            _self.http(url, $(this).attr('rel'), $(this).serializeArray(), $(this).attr('method'));
        });
        //锚点处理
        $('a[href^="#"]', _box).click(function (e) {
            e.preventDefault();
            var anchor = $(this).attr('href').substr(1);
            if ($('#' + anchor).size() > 0) {
                _self.scrollTop($('#' + anchor), _self.op.anchor_move_speed);
            } else if ($('a[name="' + anchor + '"]').size() > 0) {
                _self.scrollTop($('a[name="' + anchor + '"]'), _self.op.anchor_move_speed);
            } else {
                _self.scrollTop(0, _self.op.anchor_move_speed);
            }
        });

        $.each(this.op._ready, function (k, fun) {
            fun(selector);
        })

    },
    //请求接口， 支持情况：1, 请求接口同时渲染模板 2,只请求模板不请求接口 3,只请求接口不渲染模板， 如果有更复杂的逻辑可以自己封住函数,调TPM.sendAjax, TPM.render。
    http: function (url, rel, data, type) {
        rel = rel || this.op.main;
        type = type || 'get';
        //分析url，如果./开始直接请求模板
        if ('./' == url.substr(0, 2)) {
            this.render(url, rel);
            $('#' + rel).data('url', url);

            if (this.op.main == rel && 'get' == type.toLowerCase()) this.changeHash(url);
            return;
        }
        //分析模板地址
        var tpl_path = this.route(url);
        //改变hash
        if (tpl_path && this.op.main == rel && 'get' == type.toLowerCase()) this.changeHash(url);
        //ajax请求
        var _self = this;
        this.sendAjax(url, data, type, function (response) {
            if (!tpl_path && _self.defined(response[_self.op.tpl_path_var])) {
                tpl_path = response[_self.op.tpl_path_var]; //接口可以指定模板
                //改变hash
                if (tpl_path && _self.op.main == rel && 'get' == type.toLowerCase()) _self.changeHash(url);
            }
            if (!tpl_path) {
                //如果没有模板，默认只请求ajax，请求成后刷新rel
                if ('false' != rel.toLowerCase()) _self.reload(rel);
            } else {
                //模板渲染
                _self.render(tpl_path, rel, response);
                $('#' + rel).data('url', url);
            }
        });
    },
    sendAjax: function (url, data, type, cb, async, options) {
        var _self = this;
        data = data || {};
        type = type || 'get';
        options = options || {};

        api_options = $.extend({}, _self.op, options);
        if (false !== async) {
            async == true;
        }
        //请求接口之前hook（可以用做签名）
        if ($.isFunction(api_options.before_request_api))
            data = api_options.before_request_api(data, url);
        //ajax请求
        //TODO ,以http开头的url，不加api_base
        var api_url = api_options.api_base + url;

        $.ajax(
            {
                type: type,
                url: api_url,
                data: data,
                dataType: api_options.ajax_data_type || '',
                jsonp: api_options.ajax_jsonp_callback || 'callback',
                async: async,
                success: function (d, s, x) {
                    if (redirect = x.getResponseHeader('redirect')) {
                        //跳转
                        if (api_options.single) _self.http(redirect);
                        return;
                    }
                    //接口数据分析
                    try {
                        var response = 'object' == $.type(d) ? d : $.parseJSON(d);
                    } catch (e) {
                        _self.error('-2', '接口返回数据格式错误');
                        return;
                    }
                    //接口请求后的hook
                    if ($.isFunction(api_options.after_request_api)) {
                        var hook_result = api_options.after_request_api(response, url);
                        if (undefined != hook_result) {
                            response = hook_result;
                        }
                    }
                    if (false != response && $.isFunction(cb))
                        cb(response);
                }
            }
        );
    },
    changeHash: function (url) {
        if (url != this.op.api_index) {
            this.op._old_hash = '#' + url;
            location.hash = url;
        } else {
            if ('' != this.op._old_hash) this.op._old_hash = this.isIE() ? '#' : '';//IE如果描点为# 获得值不为空
            if ('' != location.hash) location.hash = '';//赋值为空其实浏览器会赋值为 #
        }
    },
    //渲染模板
    render: function (tpl_path, rel, vars) {
        vars = vars || {};
        var _self = this;
        $.get(tpl_path, function (d, x, s) {
            //模板解析
            var content = _self.parseTpl(d, vars);
            //解析模板替换变量
            $.each(_self.op.tpl_parse_string, function (find, replace) {
                var matcher = new RegExp(find.replace(/[-[\]{}()+?.,\\^$|#\s]/g, '\\$&'), 'g');
                content = content.replace(matcher, replace);
            });
            //分离js
            var ret = _self.stripScripts(content);
            var html = ret.text;
            var js = ret.scripts;
            $('#' + rel).empty().append(html);
            _self.initUI($('#' + rel));
            //执行页面js
            _self.execScript(js, $('#' + rel));

        }, 'text');
    },
    //重新加载区域内容
    reload: function (rel) {
        var url = $('#' + rel).data('url');
        if (url) {
            this.http(url, rel);
        }
    },
    //路由解析
    route: function (url) {
        var tpl_path = false;
        var _self = this;
        $.each(this.op.routes, function (route, path) {
            if (_self._routeToRegExp(route).test(url)) {
                tpl_path = path;
                return false;
            }
        });
        return tpl_path;
    },
    _routeToRegExp: function (route) {
        var namedParam = /:\w+/g;
        var splatParam = /\*\w+/g;
        var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;
        route = route.replace(escapeRegExp, '\\$&')
            .replace(namedParam, '([^\/]+)')
            .replace(splatParam, '(.*?)');
        return new RegExp('^' + route + '$');
    },
    //模板解析
    parseTpl: function (tplContent, vars) {
        return this.op.tpl(tplContent, vars);
    },
    ajaxError: function (xhr, ajaxOptions, thrownError) {
        window.TPMshowAjaxWait = true;
        TPM.info('网络异常');
    },


    //------实用工具
    //判断是否为IE
    isIE: function () {
        return /msie [\w.]+/.exec(navigator.userAgent.toLowerCase());
    },
    //判断是否为IE7以下浏览器
    isOldIE: function () {
        return this.isIE() && (!docMode || docMode <= 7);
    },
    //移动滚动条,n可以是数字也可以是对象
    scrollTop: function (n, t, obj) {
        t = t || 0;
        obj = obj || 'html,body'
        num = $.type(n) != "number" ? n.offset().top : n;
        $(obj).animate({
            scrollTop: num
        }, t);
    },
    //分离js代码
    stripScripts: function (codes) {
        var scripts = '';
        //将字符串去除script标签， 并获得script标签中的内容。
        var text = codes.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function (all, code) {
            scripts += code + '\n';
            return '';
        });
        return {text: text, scripts: scripts}
    },
    //执行js代码
    execScript: function (scripts, _box) {
        if (scripts != '') {
            //执行js代码, 在闭包中执行。改变$选择符。
            var e = new Function('$', scripts);
            var selector = function (obj) {
                var $obj = $(obj, _box)
                return $obj.size() > 0 ? $obj : $(obj);
            };
            e(selector);

        }
    },
    //判断变量是否定义
    defined: function (variable) {
        return $.type(variable) == "undefined" ? false : true;
    },
    //获得get参数
    get: function (name) {
        if ('undefined' == $.type(this._gets)) {
            var querystring = window.location.search.substring(1);
            var gets = {};
            var vars = querystring.split('&')
            var param;
            for (var i = 0; i < vars.length; i++) {
                param = vars[i].split('=');
                gets[param[0]] = param[1];
            }
            this._gets = gets;
        }
        return this._gets[name];
    }

};





